package com.urule.service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.bstek.demo.entity.UserInfo;
import com.urule.utils.JsonUtils;
import com.bstek.urule.console.database.manager.group.GroupManager;
import com.bstek.urule.console.database.model.Group;
import com.bstek.urule.exception.RuleException;
import org.apache.commons.lang.StringUtils;

import com.bstek.urule.console.database.service.user.UserService;
import com.bstek.urule.console.security.entity.DefaultUser;
import com.bstek.urule.console.security.entity.User;
import com.bstek.urule.console.security.provider.SecurityProvider;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * 单点登录：登录集成
 * @date 2023/8/22
 */
//@Service(SecurityProvider.BEAN_ID)
public class DefaultSecurityProvider implements SecurityProvider {

	@Resource(name=UserService.BEAN_ID)
	UserService userService;

	/**
	 * 获取登录用户对象,同时需要初始化用户团队信息，在浏览器打开以下地址进行测试验证：
	 * (1)进入'我'的团队工作台http://localhost:8080/urule/group?groupId=bstek-tsd&&token=hans
	 * (2)进入团队选择画面http://localhost:8080/urule/group/select?token=hans
	 * @param req HttpServletRequest
	 * @return 返回用户对象
	 */
	@Override
	public User getLoginUser(HttpServletRequest req) {
		Object userObject=req.getSession().getAttribute("urule.user");
		//TODO 重写：模拟读取token，用token从【用户登录认证中心】换取用户详细信息
		//大多数生产场景中是从header中读token
		//String token=req.getHeader("token");
		String token=req.getParameter("token");
		if(token!=null) {
			if(userObject!=null){
				User u= (User) userObject;
				if(u.getName().equals(token)){
					// 输入的token和当前登录用户session是同一个人
					return u;
				}
			}
			try {
				//模拟调用第三方用户登录认证中心，换取用户详细信息
				RestTemplate client = new RestTemplate();
				StringBuilder sb = new StringBuilder("http://localhost:8081/rest");
				sb.append("/test/sso/sign?");
				//添加应用编号参数
				sb.append("token=").append(token);
				String str = client.getForObject(sb.toString(), String.class);
				System.out.println("认证中心返回消息=" + str);
				if (StringUtils.isNotBlank(str)) {
					UserInfo userInfo = JsonUtils.fromJSON(str, UserInfo.class);
					//FIXME 用户绑定的团队groups不能为空值，否则会报权限不足
					List<Group> groups = GroupManager.ins.createQuery().list(userInfo.getId());
					//注意：DefaultUser没有默认的构造方法
					DefaultUser user = new DefaultUser(userInfo.getId(), userInfo.getName(), groups);
					req.getSession().setAttribute("urule.user", user);//放到session中
					System.out.println("认证中心用信息=" + userInfo.toString());
					return user;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}else{
			// token为空时，走urule默认的方式
			if(userObject!=null){
				User u= (User) userObject;
				return u;
			}
		}
		// FIXME 没有正常匹配到用户，需要跳转到认证中心登录页面...
		throw new RuleException("自定义用户异常：需要跳转到认证中心登录页面...");
	}

	/**
	 * 执行登录操作
	 * @param req HttpServletRequest
	 * @param account 账号
	 * @param password 密码
	 */
	@Override
	public void login(HttpServletRequest req, String account, String password) {
		com.bstek.urule.console.database.model.User user = userService.validate(account, password);
		User securityUser = new DefaultUser(user.getId(), user.getName(), user.getGroups());
		req.getSession().setAttribute("urule.user", securityUser);
	}

	/**
	 * 执行登出操作
	 * @param req HttpServletRequest
	 */
	@Override
	public void logout(HttpServletRequest req) {
		req.getSession().removeAttribute("urule.user");
	}

}
